package com.ns.attendance.core;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ns.attendance.dao.model.Users;
import com.ns.attendance.util.DaysUtil;
import com.ns.attendance.util.EmailSend;
import com.ns.attendance.util.HttpUtil;
import com.ns.attendance.util.LoadConfig;

/**
 * @author Han
 */
public class CheckAttendance {
	private static Logger log = LoggerFactory.getLogger(CheckAttendance.class);

	private static final String BEGIN_TIME = "09:30:00";
	private static final String END_TIME = "18:30:00";
	
	public static void initClient() throws Exception{
		 Map<String, String> loginMap = new HashMap<String, String>();
		 loginMap.put("username", LoadConfig.getValue("os.username"));
		 loginMap.put("password", LoadConfig.getValue("os.password"));
		 // 登录
		
		 String response = HttpUtil.excutePost(LoadConfig.getValue("check.login.url"), loginMap);
		
		 if (!response.trim().equals("result=2")) {
			 log.error(response);
			 log.error("登录失败...");
			 throw new Exception("登录失败");
		 }
	}
	
	public static void notice(Users user,boolean checkMonth) {
		String previousDay = new SimpleDateFormat("yyyy-MM-dd").format(DaysUtil.getPreviousDay());
		log.info("查询"+user.getName()+","+user.getId()+"的"+previousDay+"打卡记录...");
		
		String title = null;
		StringBuffer content = null;
		try {
			List<Record> datas = getRecords(String.valueOf(user.getId()),null,previousDay);
			List<String> days = new ArrayList<String>();
			days.add(previousDay);
			
			List<String> result = checkRecords(datas,days);
			
			if(!result.isEmpty()){
				title = previousDay+"打卡有异常，请注意";
				content = new StringBuffer();
				for(String str : result){
					content.append(str+"\r\n");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(user.getName()+","+user.getId()+"查询异常...");
			log.error(getErrorInfoFromException(e));
			title = "前一天打卡检测执行异常，"+e.getClass();
			content = new StringBuffer(getErrorInfoFromException(e));
		}
		
		try {
			if(StringUtils.isNotEmpty(title)){
				EmailSend.sendTextMsg(title, content.toString(), user.getEmail());
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(user.getName()+","+user.getId()+"邮件发送异常...");
			log.error(getErrorInfoFromException(e));
		}
		//月打卡记录汇总
		if(checkMonth && user.isMonthly()){
			Calendar firstDay = Calendar.getInstance();
			firstDay.add(Calendar.MONTH, -1);
			firstDay.set(Calendar.DAY_OF_MONTH, 1);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String firstDayOfMonth = sdf.format(firstDay.getTime());
			
			
			Calendar lastDay = Calendar.getInstance();
			lastDay.add(Calendar.MONTH, -1);
			lastDay.set(Calendar.DAY_OF_MONTH, lastDay.getActualMaximum(Calendar.DAY_OF_MONTH));
			String lastDayOfMonth = sdf.format(lastDay.getTime());
			
			int month = firstDay.get(Calendar.MONTH);
			List<String> days = new ArrayList<String>();
			while(firstDay.get(Calendar.MONTH) == month){
				if(DaysUtil.isWorkDay(firstDay)){
					days.add(sdf.format(firstDay.getTime()));
				}
				firstDay.add(Calendar.DATE, 1);
			}
			
			try {
				List<Record> datas = getRecords(String.valueOf(user.getId()),firstDayOfMonth,lastDayOfMonth);
				List<String> result = checkRecords(datas,days);
				
				title = "上月打卡记录汇总，请注意";
				content = new StringBuffer();
				for(String str : result){
					content.append(str+"\r\n");
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				log.error(user.getName()+","+user.getId()+"查询异常...");
				log.error(getErrorInfoFromException(e));
				title = "上个月打卡检测执行异常，"+e.getClass();
				content = new StringBuffer(getErrorInfoFromException(e));
			}
			
			try {
				if(StringUtils.isNotEmpty(title)){
					EmailSend.sendTextMsg(title, content.toString(), user.getEmail());
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error(user.getName()+","+user.getId()+"邮件发送异常...");
				log.error(getErrorInfoFromException(e));
			}
		}
	}

	public static List<Record> getRecords(String userid,String fromDate, String toDate){

		Map<String, String> queryMap = new HashMap<String, String>();
		queryMap.put("UserID__id__exact",userid);
		if (fromDate == null) {
			queryMap.put("fromTime", toDate);
		} else {
			queryMap.put("fromTime", fromDate);
		}
		queryMap.put("toTime", toDate);
		
		String response = HttpUtil.excuteGet(LoadConfig.getValue("check.query.url"), queryMap);
		Gson gson = new Gson();

		List<Record> datas = gson.fromJson(response, new TypeToken<List<Record>>() {
		}.getType());

		return datas;
	}

	/**
	 * 打卡记录比对
	 * 
	 * @param datas
	 * @param days
	 * @return
	 * @throws ParseException
	 */
	public static List<String> checkRecords(List<Record> datas, List<String> days) throws ParseException {
		List<String> result = new ArrayList<String>();

		Map<String, List<String>> dataMap = new HashMap<String, List<String>>();

		for (Record data : datas) {
			String date = data.getDate();
			if (dataMap.containsKey(date)) {
				List<String> temp = dataMap.get(date);
				temp.add(data.getTTime());
			} else {
				List<String> temp = new ArrayList<String>();
				temp.add(data.getTTime());
				dataMap.put(date, temp);
			}
		}

		for (String day : days) {
			Date thisDate = new SimpleDateFormat("yyyy-MM-dd").parse(day);
			String thisDateStr = new SimpleDateFormat("yyyy-MM-dd EEEE").format(thisDate);

			List<String> temp = dataMap.get(day);
			if (temp == null || temp.isEmpty()) {
				result.add(thisDateStr + ",当天异常,没有查到打卡记录");
				continue;
			}

			Collections.sort(temp);
			String start = temp.get(0);
			String end = temp.get(temp.size() - 1);

			if (start.compareTo(day + " " + BEGIN_TIME) > 0) {
				result.add(thisDateStr + "," + start + ",上午异常");
			}
			if (end.compareTo(day + " " + END_TIME) < 0) {
				result.add(thisDateStr + "," + end + ",下午异常");
			}
		}

		return result;
	}
	
	
	public static String getErrorInfoFromException(Exception e) {
		try {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			return "\r\n" + sw.toString() + "\r\n";
		} catch (Exception e2) {
			return "bad getErrorInfoFromException";
		}
	}
}
